package com.miku.controller;

import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

@Api(tags = "队列测试接口")
@RestController
@RequestMapping("/queue")
@Slf4j
public class QueueController {

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;



    @GetMapping("/add")
    // 接收一个参数name，然后将任务添加到线程池中
    public void add(String name) {
        // 使用CompletableFuture运行一个异步任务
        CompletableFuture.runAsync(() -> {
            executeWithRetry(name,3,1000);
        }, threadPoolExecutor);
    }

    /**
     * 执行任务，如果失败则重试
     * @param name
     * @param maxRetries
     * @param delayMillis
     */
    private void executeWithRetry(String name, int maxRetries, int delayMillis) {
        boolean success=false;
        int attempts = 0;
        while (!success && attempts < maxRetries) {
            log.info("任务执行中:{},执行人:{}",name,Thread.currentThread().getName());
            try {
                //模拟线程运行时间长
                Thread.sleep(60000);
                success = true;
            } catch (InterruptedException e) {
                //保持线程中端状态
               Thread.currentThread().interrupt();
               log.info("任务执行中断:{}",name);
            }catch (Exception e){
                attempts++;
                log.info("任务执行失败,正在第:{}次重试",attempts);

                try {
                    //等待一段时间重试
                    Thread.sleep(delayMillis);
                } catch (InterruptedException ex) {
                 Thread.currentThread().interrupt();//保证中断状态
                }
            }
        }
        if (!success) {
            log.info("任务执行失败,达到最大重试次数:{}",name);
        }
    }

    @GetMapping("/get")
    // 该方法返回线程池的状态信息
    public String get() {
        // 创建一个HashMap存储线程池的状态信息
        Map<String, Object> map = new HashMap<>();
        // 获取线程池的队列长度
        int size = threadPoolExecutor.getQueue().size();
        // 将队列长度放入map中
        map.put("队列长度", size);
        // 获取线程池已接收的任务总数
        long taskCount = threadPoolExecutor.getTaskCount();
        // 将任务总数放入map中
        map.put("任务总数", taskCount);
        // 获取线程池已完成的任务数
        long completedTaskCount = threadPoolExecutor.getCompletedTaskCount();
        // 将已完成的任务数放入map中
        map.put("已完成任务数", completedTaskCount);
        // 获取线程池中正在执行任务的线程数
        int activeCount = threadPoolExecutor.getActiveCount();
        // 将正在工作的线程数放入map中
        map.put("正在工作的线程数", activeCount);
        // 将map转换为JSON字符串并返回
        return JSONUtil.toJsonStr(map);
    }

}
